#include "../include/strings.h"
#include "../include/gdtFront.h"
#include "../include/defs.h"
#include "../include/driverVideo.h"
#include "../include/kasm.h"
#include "../include/gdt.h"
#include "../include/shell.h"

extern DESCR_SEG gdt[100];			/* GDT de 255 entradas*/
extern GDTR gdtr;
/*le pide al usuario que cargue la direccion base, y la escribe en un vector de char. 
Si el dato ingresado no es ni un numero ni un caracter devuelve dato incorrecto y 
pide que vuelva a ingresar*/
void
paramGdt(void)
{
	int  dpl, s, e, indice, g=0;
	int dirBase, limite;
	
	do
	{	print("Ingrese el indice donde desea ubicar el segmento:  ");
		indice=getHexa();}
	while(indice<=4);
	isEnter();putc(' ',1);
	isEnter();
	
	print("El segmento que desea agregar es de tipo:  \n");
	print("1. De sistema: puerta de llamada, TSS, etc.  \n");
	print("2. Normal: codigo datos o pila.  \n");
	do
	{	print("Ingrese su eleccion ( 1 - 2):  ");
		s=getint();
	}
	while((s!=1) && (s!=2));
	s--;
	isEnter();putc(' ',1);
	isEnter();
	
	print("Indique el nivel de privilegio del segmento:  \n");
	print("1. Privilegio nivel 0 (Maximo).  \n");
	print("2. Privilegio nivel 1.  \n");
	print("3. Privilegio nivel 2.  \n");
	print("4. Privilegio nivel 3 (Minimo).  \n");	
	do
	{	print("Ingrese su eleccion ( 1 - 4):  ");
		dpl=getint();
	}
	while( dpl<1  || dpl>4 );
	isEnter();putc(' ',1);
	isEnter();
	dpl--;
	
	print("Indique el Tipo del segmento:  \n");
	print("1. De codigo.  \n");
	print("2. De dato.  \n");	
	do
	{	print("Ingrese su eleccion ( 1 - 2):  ");
		e=getint();
	}
	while((e!=1) && (e!=2));
	isEnter();putc(' ',1);
	isEnter();
	e--;
	
	do
	{	print("Ingrese Direccion base en Hexadecimal:  \n");
		dirBase=getHexa();
	}
	while(dirBase<0);
	isEnter();putc(' ',1);
	isEnter();
	
	do
	{
		print("Ingrese Direccion Limite en Hexadecimal:  \n");
		limite=getHexa();
	}
	while((limite>0xfffff) || (limite<=0));
	isEnter();putc(' ',1);
	isEnter();
	if(limite>0xfffff)
	{	g=1;
		limite = (limite>>12);
	}
	
	cargaGdt(dirBase, limite,  dpl, s, e, g, indice);
	
	print("El segmento ha sido cargado correctamente en la Tabla de Descriptores.");	
} 

void
infoGdt(void)
{	int i;
	print("TABLA DE DESCRIPTORES GLOBAL:\n");
	isEnter();
	for(i=0; i<= MAXDESCGDT; i++)
		if((gdt[i].access & 0x80)!=0)
		{	impGdt(i);
			isEnter();
		}
	
}
void
infoDesc(void)
{	int i;
	do
	{	print("Ingrese indice del descriptor en Hexadecimal:   ");
		i=getHexa();
		isEnter();
	}
	while((i>MAXDESCGDT) || (i<0));
	print("DESCRIPTOR:\n");
	isEnter();
	impGdt(i);
	isEnter();
}
void
impGdt(int i)
{	
	unsigned int dirBase,dirBaseh,dirBasem,dirBasel, limite, limh;
	dirBase=0;
	limite=0;
	STANDARTGDT descript_aux;
	
	standartGdt(i, &descript_aux );
		
	print("gdt[0x");printHexa(i,1);print("]=");
	if(descript_aux.E == 0)
		print("Data segment");
	else
		print("Code segment");
	
	print(", linearadd=");printHexa(descript_aux.dirBase,1);
	print(", limit=");printHexa(descript_aux.limite,1);
	
	if(descript_aux.G)
		print(" * 4K");
	
	print(" bytes");
	
	if(descript_aux.E == 0)
		print(", Read/Write ");
	else
		print(", Execute/Read ");
	if(descript_aux.C)
		print(", Conforming ");
	if(descript_aux.A)
		print(", Accessed ");
	
	isEnter();
	
}
void
escMem(void)
{	int i, flag=1;
	char c[BUFSHELL];
	char entrada;
	int indice, offset, dim;
	i=0;
	
	do
	{	
	  print("Ingrese el indice del segmento donde desea escribir:  ");
	  indice=getHexa();
	}
	while(indice<=4);
	isEnter();putc(' ',1);
	isEnter();
	
	
	print("Ingrese el texto que desea agregar:  ");
	do
	{	
		entrada = getc(0);
		
		if( entrada == KEY_ENTER)
		{	c[i]='\0';
			flag=0;
		}
		else if( entrada == BKSP)
		{
			  if(i != 0)
			  {	i--;
				isBksp();
			  }
		}
		else if(i< (BUFSHELL -1))
		{	
			c[i++]= entrada;
			putc(entrada,1);
		}
		
	}while(flag);
	isEnter();putc(' ',1);
	isEnter();
	
	
	do{	print("Ingrese desplazamiento:  ");
		offset=getint();}
	while(offset<0);
	isEnter();putc(' ',1);
	isEnter();
	
	dim=strln(c);
	
	memWrite( indice, offset, c, dim);
}
void
leeMem(void)
{	int i, flag=1;
	char c[BUFSHELL];
	char entrada;
	int indice, offset, dim;
	i=0;
	
	do
	{	
	  print("Ingrese el indice del segmento que desea leer:  ");
	  indice=getHexa();
	}
	while(indice<=4);
	isEnter();putc(' ',1);
	isEnter();
	
		
	do{	print("Ingrese desplazamiendo:  ");
		offset=getint();}
	while(offset<0);
	isEnter();putc(' ',1);
	isEnter();
	
	do{	print("Ingrese la longitud:  ");
		dim=getint();}
	while(dim<0);
	isEnter();putc(' ',1);
	isEnter();
	
	memRead( indice, offset, dim);
}
	
	
	